package moodish.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;

import moodish.comm.ClientComm;
import moodish.dummy.ClientMainDummy;

public class ClientInterface {
	
	public static final int WINDOW_SIZE_X = 900, WINDOW_SIZE_Y = 500;
	private static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
	public ClientComm clientComm;
	
	private JPanel centerPanel;
	private JFrame janela;
	
	private HashMap<String, Boolean> connectedClientsList = new HashMap<String, Boolean>();
	private DefaultListModel<String> listModel = new DefaultListModel<String>();
	private JList<String> clientList;
	
	class friendsListCellRenderer extends JLabel implements ListCellRenderer<Object> {
		private static final long serialVersionUID = 1L;

		public friendsListCellRenderer() {
	         setOpaque(true);
	     }

	     public Component getListCellRendererComponent(JList<?> list,
	                                                   Object value,
	                                                   int index,
	                                                   boolean isSelected,
	                                                   boolean cellHasFocus) {
	         setText(value.toString());
	         if(connectedClientsList.get(value.toString()) == Boolean.TRUE){
	        	 setForeground(Color.GREEN);
	         } else {
	        	 setForeground(Color.BLACK);
	         }
	         setBackground(Color.WHITE);
	         return this;
	     }
	 }
	
	public class disconnectListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			close();
		}
	}
	
	public class addFriendListener implements ActionListener {
		JTextField friendName;
		JFrame addFriendWindow;
		@Override
		public void actionPerformed(ActionEvent e) {
			addFriendWindow = new JFrame("Add new friend!");
			addFriendWindow.setSize(400,100);
			addFriendWindow.setLocation((int) (screenSize.getWidth()/2 - 200), (int) (screenSize.getHeight()/2-50));
			
			Container cp = addFriendWindow.getContentPane();
			friendName = new JTextField(25);
			JButton addF = new JButton("Add Friend!");
			
			cp.setLayout(new FlowLayout());
			cp.add(friendName);
			cp.add(addF);
			
			addF.addActionListener(new ActionListener(){
				@Override
				public void actionPerformed(ActionEvent arg0) {
					clientComm.friendship(friendName.getText());
					addFriendWindow.setVisible(false);
					if(connectedClientsList.containsKey(friendName.getText())){
						friendship(friendName.getText());
					}
				}
			});
			
			addFriendWindow.setVisible(true);
		}
	}
	
	public class unfriendListener implements ActionListener {
		JTextField friendName;
		JFrame unriendWindow;
		@Override
		public void actionPerformed(ActionEvent e) {
			unriendWindow = new JFrame("Remove friend!");
			unriendWindow.setSize(400,100);
			unriendWindow.setLocation((int) (screenSize.getWidth()/2 - 200), (int) (screenSize.getHeight()/2-50));
			
			Container cp = unriendWindow.getContentPane();
			friendName = new JTextField(25);
			JButton addF = new JButton("Add Friend!");
			
			cp.setLayout(new FlowLayout());
			cp.add(friendName);
			cp.add(addF);
			
			addF.addActionListener(new ActionListener(){
				@Override
				public void actionPerformed(ActionEvent arg0) {
					clientComm.unfriendship(friendName.getText());
					unriendWindow.setVisible(false);
					if(connectedClientsList.containsKey(friendName.getText())){
						unfriendship(friendName.getText());
					}
				}
			});
			
			unriendWindow.setVisible(true);
		}
	}
	
	public class setNewMoodListener implements ActionListener {
		JFrame newMoodWindow;
		JTextField moodText;
		@Override
		public void actionPerformed(ActionEvent arg0) {
			newMoodWindow = new JFrame("Set new mood");
			newMoodWindow.setSize(350,100);
			newMoodWindow.setLocation((int) (screenSize.getWidth()/2 - 200), (int) (screenSize.getHeight()/2-50));
			
			Container cp = newMoodWindow.getContentPane();
			moodText = new JTextField(25);
			JButton addF = new JButton("Set Mood!");
			
			cp.setLayout(new FlowLayout());
			cp.add(moodText);
			cp.add(addF);
			
			addF.addActionListener(new ActionListener(){
				@Override
				public void actionPerformed(ActionEvent arg0) {
					String mood = moodText.getText();
					if(!mood.isEmpty()){
						clientComm.sendMoodishMessage(mood);
						newMoodWindow.setVisible(false);
					} else {
						JOptionPane.showMessageDialog(null, "Mood can't be blank!", "Error", JOptionPane.WARNING_MESSAGE);
					}
				}
			});
			
			newMoodWindow.setVisible(true);
		}
	}
	
	public void close(){
		System.out.println("Disconnecting.");
		if(clientComm.isConnected()){
			clientComm.disconnect();
		}
        System.exit(0);
	}
	
	public void refreshUI(){
		centerPanel.repaint();
		janela.repaint();
		janela.revalidate();
	}
	
	public void addMood(String user, String mood){
		Mood newMood = new Mood(user, mood);
		centerPanel.add(newMood);
		refreshUI();
		clientList.repaint();
	}
	
	public ClientInterface(ClientComm clientComm){
		this.clientComm = clientComm;
		double width = screenSize.getWidth();
        double height = screenSize.getHeight();
        janela = new JFrame("Moodish Client ("+ClientMainDummy.nickname.getText()+" connected to "+ClientMainDummy.serverAddress.getText()+")");
        janela.setSize(WINDOW_SIZE_X,WINDOW_SIZE_Y);
        janela.setLocation((int) (width/2 - WINDOW_SIZE_X/2), (int) (height/2-WINDOW_SIZE_Y/2));

        Container cp = janela.getContentPane();
        cp.setLayout(new BorderLayout());
        
        //GridLayout centerLayout = new GridLayout(2,4,20,20);
        FlowLayout centerLayout = new FlowLayout(FlowLayout.LEFT, 10, 10);
        centerPanel = new JPanel(centerLayout);
        //centerPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
        JPanel actions = new JPanel(new FlowLayout());
        
        JButton disconnect = new JButton("Disconnect");
        JButton setNewMood = new JButton("Send a new mood");
        JButton addNewFriend = new JButton("Add Friend");
        JButton unFriend = new JButton("Remove Friend");
        
        actions.add(disconnect);
        actions.add(setNewMood);
        actions.add(addNewFriend);
        actions.add(unFriend);
        
        //listModel.addElement("Teste");
        clientList = new JList<String>(listModel);
        clientList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        clientList.setPreferredSize(new Dimension(100, 460));
        clientList.setCellRenderer(new friendsListCellRenderer());
        
        cp.add(centerPanel, BorderLayout.CENTER);
        cp.add(actions, BorderLayout.SOUTH);
        cp.add(clientList, BorderLayout.EAST);
        
        disconnect.addActionListener(new disconnectListener());
        setNewMood.addActionListener(new setNewMoodListener());
        addNewFriend.addActionListener(new addFriendListener());
        unFriend.addActionListener(new unfriendListener());
        
        janela.addWindowListener(new java.awt.event.WindowAdapter() {
            @Override
            public void windowClosing(java.awt.event.WindowEvent windowEvent) {
            	close();
            }
        });
        janela.setVisible(true);
	}

	public void connectedClient(String payload) {
		connectedClientsList.put(payload, false);
		listModel.addElement(payload);
	}
	
	public void disconnectedClient(String payload){
		connectedClientsList.remove(payload);
		listModel.removeElement(payload);
	}

	public void friendship(String payload) {
		connectedClientsList.put(payload, true);
		clientList.repaint();
	}

	public void unfriendship(String payload) {
		connectedClientsList.put(payload, false);
		clientList.repaint();
	}
}
